<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>

        function roman2num1 (roman) {
            if (!roman) {
                return 0;
            }
            const mapping = {
                I: 1,
                V: 5,
                X: 10,
                L: 50,
                C: 100,
                D: 500,
                M: 1000,
            };
            // III
            // IV
            const len = roman.length;
            let sum = mapping[roman[len - 1]];
            // 从后往前循环
            for (let i = len - 2; i >= 0; i--) {
                const letter = roman[i];
                const nextLetter = roman[i + 1];
                // 去映射中找到字母对应的数字
                const currentNum = mapping[letter];
                const nextNum = mapping[nextLetter];
                // 比较前当前数字和后一个数字
                if (currentNum < nextNum) {
                    sum -= currentNum;
                } else {
                    // 求和
                    sum += currentNum;
                }
            }
            return sum;
        }

        // console.log(roman2num1('III')); // 3
        // console.log(roman2num1('IV')); // 4
        // console.log(roman2num1('IX')); // 9
        // console.log(roman2num1('LVIII')); // 58
        // console.log(roman2num1('MCMXCIV')); // 1994

        // 映射的处理方案
        // 1. object
        // 2. switch
        
        // V >>> 5
        // I >>> 1
        function getNumber (letter) {
            switch (letter) {
                case 'I': return 1;
                case 'V': return 5;
                case 'X': return 10;
                case 'L': return 50;
                case 'C': return 100;
                case 'D': return 500;
                case 'M': return 1000;
                default: return 0;
            }
        }

        function roman2num2 (roman) {
            if (!roman) {
                return 0;
            }
           
            const len = roman.length;
            let sum = getNumber(roman[len - 1]);
            // 从后往前循环
            for (let i = len - 2; i >= 0; i--) {
                const letter = roman[i];
                const nextLetter = roman[i + 1];
                // 去映射中找到字母对应的数字
                const currentNum = getNumber(letter);
                const nextNum = getNumber(nextLetter);
                // 比较前当前数字和后一个数字
                if (currentNum < nextNum) {
                    sum -= currentNum;
                } else {
                    // 求和
                    sum += currentNum;
                }
            }
            return sum;
        }

        // console.log(roman2num2('III')); // 3
        // console.log(roman2num2('IV')); // 4
        // console.log(roman2num2('IX')); // 9
        // console.log(roman2num2('LVIII')); // 58
        // console.log(roman2num2('MCMXCIV')); // 1994

        function performance (name, cb, count = 100000) {
            console.time(name);
            for (let i = 0; i < count; i++) {
                cb();
            }
            console.timeEnd(name);
        }

        performance('object:', function () {
            roman2num1('MCMXCIV');
        }, 1000000);

        performance('switch:', function () {
            roman2num2('MCMXCIV');
        }, 1000000);

    </script>
</body>
</html>